#ifndef STRING_HPP
#define STRING_HPP

#include <std/cstddef>
#include <std/cstdint>

namespace str
{
	size_t length(const char* str);
	char* copy(char* dest, const char* src);
	char* concat(char* dest, const char* src, size_t n);

	template <typename T>
	char* numberToString(char* dest, size_t bufferLength, T arg,
			unsigned int numericBase = 10u, bool showBase = false);

}

namespace str
{

template <typename T>
char* toString(char* dest, size_t bufferLength, T arg, unsigned int numericBase = 10, bool showBase = false)
{

	static constexpr const char* alphabet = "0123456789abcdef";

	static constexpr const char* prefixes[] = {"", "0b", "", "", "", "",
		"", "0", "", "", "", "", "", "", "", "0x"};

	size_t i{0};
	const T zero{static_cast<T>(0)};

	// Insert the minus sign if needed
	if(arg < zero) {
		dest[i++] = '-';
		arg = -arg;
	}
	if(showBase)
	{
		const char* baseString{prefixes[numericBase - 1]};
		copy(&dest[i], baseString);
		i += length(baseString);
	}
	// Insert the zero character if needed (won't be done otherwise)
	if(arg == zero)
		dest[i++] = '0';

	size_t firstDigit{i};

	while(arg > zero and i < bufferLength)
	{
		dest[i++] = alphabet[arg % numericBase];
		arg /= numericBase;
	}

	size_t lastDigit{i - 1};

	dest[i++] = '\0';

	char tmp;
	while(firstDigit < lastDigit)
	{
		tmp = dest[lastDigit];
		dest[lastDigit] = dest[firstDigit];
		dest[firstDigit] = tmp;
		firstDigit++;
		lastDigit--;
	}

	return dest;
}

}

#endif
